#include "spi.h"
#include "gpio.h"

#define DECODE_MODE  0x09
#define INTENSITY    0x0A
#define SCAN_LIMIT   0x0B
#define SHUT_DOWN    0x0C
#define DISPLAY_TEST 0x0F

const uint8_t numbers[]={
0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xD6,0xD6,  // -0-.  
0xE6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,  // -1-  
0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,  
0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,  // -2-  
0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00,  
0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,  // -3-  
0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,  
0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,  // -4-  
0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00,  
0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x0E,  // -5-  
0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,  
0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,  // -6-  
0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,  
0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,  // -7-  
0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,  
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,  // -8-  
0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, 
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,  // -9-  
0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00};

void MAX7219_write(uint8_t addr, uint8_t dat)
{
    SPI_SetCsLow();
    Spi_TxRx(addr);
    Spi_TxRx(dat);
    SPI_SetCsHigh();
}

void MAX7219_init(void)
{
    MAX7219_write(SHUT_DOWN,    0x01);      // 0x00:shutdown, 0x01:normal
    MAX7219_write(DECODE_MODE,  0x00);      // Bypass code B decoder, no-decode operation
    MAX7219_write(SCAN_LIMIT,   0x07);      // Scan-limit, 0:1-digit, 1:2-digits, ... 7:8-digits
    MAX7219_write(INTENSITY,    0x01);      // 0x00:min, 0xFF:max
    MAX7219_write(DISPLAY_TEST, 0x00);      // 0x00:normal, 0x01:test mode
}

int main(void)
{
    stc_spi_config_t  SPIConfig;
    uint8_t pos = 0, size = sizeof(numbers), i, j;

    CLK_EnablePeripheralClk(ClkPeripheralSpi);
    CLK_EnablePeripheralClk(ClkPeripheralGpio);

    Gpio_SetFunc_SPI_CS_P03();
    Gpio_SetFunc_SPI_MOSI_P24();
    Gpio_SetFunc_SPI_CLK_P25();

    SPIConfig.bCPHA = SpiClockPhaseFirst;
    SPIConfig.bCPOL = SpiClockPolarityLow;
    // Turn off interrupts
    SPIConfig.bIrqEn = FALSE;
    // Master mode
    SPIConfig.bMasterMode = SpiMaster;
    // Clock source, PCLK/2
    SPIConfig.u8ClkDiv = SpiClkDiv2;
    // No callback
    SPIConfig.pfnIrqCb = NULL;
    Spi_Init(&SPIConfig);

    MAX7219_init();

    while(1)
    {
        for (i = 0; i < 8; i++)
        {
            j = (pos + i) % size;
            MAX7219_write(i + 1, numbers[j]);
        }
        pos = (pos + 1) % size;
        delay1ms(100);
    }
}
